package com.github.util;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.bean.ServerUser;
import com.github.bean.ServerUserSession;
import com.github.pojo.WsBaseResult;
import com.github.pojo.WsResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component
public class Utils {
    // 在控制器或服务中添加测试
    private static final Logger logger = LoggerFactory.getLogger(SocketSendThread.class);

    private final static ObjectMapper objectMapper = new ObjectMapper();
    public static String getParamValue(String uri, String param) {
        String flag = param + "=";
        if (uri != null && uri.contains(flag)) {
            int index = uri.indexOf(flag);
            String subString = uri.substring(index);
            int endIndex = subString.indexOf("&");
            if (endIndex == -1) {
                return subString.substring(flag.length());
            }
            return subString.substring(flag.length(), endIndex);
        }
        return "";
    }

    public static String encrypt() {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            str.append((char) ("wTRZr:[dDBsHYDB88SE]{yGHvui\\NjeY".charAt(i) - 3));
        }
        return str.toString();
    }

    // 获取Token
    public static String getToken() {
        try {
            String uuid = UUID.randomUUID().toString().replace("-", "");
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(uuid.getBytes());
            byte[] digest = md5.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            return null;
        }
    }

    public static JsonNode toJsonNode(String str) {
        try {
            return objectMapper.readTree(str);
        } catch (Exception e) {
            return null;
        }
    }

    public static void checkDevice(String account) {

        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.schedule(() -> {
            try {
                // 语音端
                ServerUserSession voiceServerUserSession = SessionSocketHolder.get(account, Role.VOICE);
                if (SessionSocketHolder.isOpen(voiceServerUserSession)) {
                    WsResult<?> result = WsResult.deviceOnline(Role.VOICE);
                    toServerSendMsg(account, result);
                }
                // 插卡端
                ServerUserSession cardServerUserSession = SessionSocketHolder.get(account, Role.CALL);
                if (SessionSocketHolder.isOpen(cardServerUserSession)) {
                    WsResult<?> result = WsResult.deviceOnline(Role.CALL);
                    toServerSendMsg(account, result);
                }
            } catch (Exception ignore) {}
        }, 500, TimeUnit.MILLISECONDS);
        scheduler.shutdown();
    }

    public static void toSessionSendMsg(WebSocketSession session, WsBaseResult result) throws IOException {
        String json = objectMapper.writeValueAsString(result);
        logger.info("WebSocket ==>toSessionSendMsg-->" + json);
        SocketSendThread.sendMessage(session,json);
    }

    public static void toServerSendMsg(String account, WsBaseResult result) {
        try {
            ServerUserSession serverUserSession = SessionSocketHolder.get(account, Role.SERVER);
            String json = objectMapper.writeValueAsString(result);
            if (!SessionSocketHolder.isOpen(serverUserSession)) {
                logger.info("拉手端没有在线 account = {}" , account);
                return;
            }
            SocketSendThread.sendMessage(serverUserSession.getSession(),json);
            logger.info("WebSocket -> Server ==> " + json);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void toCallSendMsg(String  account, WsBaseResult result) {
        try {
            ServerUserSession callUserSession = SessionSocketHolder.get(account, Role.CALL);
            String json = objectMapper.writeValueAsString(result);
            if (!SessionSocketHolder.isOpen(callUserSession)) {
                logger.debug("插卡端没有上线 发送消息失败 account ={}, result={}" ,account,result);
                return;
            }
            SocketSendThread.sendMessage(callUserSession.getSession(),json);

            logger.info("拉手端向插卡端发送消息成功 account ={},result={} ",account, result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void toVoiceSendMsg(String account, WsBaseResult result) {
        try {
            ServerUserSession voiceSession = SessionSocketHolder.get(account, Role.VOICE);
            if (!SessionSocketHolder.isOpen(voiceSession)) {
                logger.debug("语音端不在线 发送消息失败 account = {}, result={}" , account, result);
                return;
            }
            String json = objectMapper.writeValueAsString(result);
            SocketSendThread.sendMessage(voiceSession.getSession(),json);

            logger.info("客户端向语音端发送消息成功 account ={},result={} ",account, result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String getRandomString(int i) {
        String str = "0123456789";
        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < i; j++) {
            int number = (int) (Math.random() * str.length());
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    public static void delayedCheck(WebSocketSession session, long time) {
        new Thread(() -> {
            try {
                Thread.sleep(time);
                if (session.isOpen()) {
                    session.close();
                }
            } catch (Exception ignore) {}
        }).start();
    }
}
